package com.euc.springbootframework.service.base;

import com.euc.springbootframework.dao.base.BaseDao;
import com.euc.springbootframework.dao.pagination.BaseConditionQuery;
import org.slf4j.LoggerFactory;

import java.lang.reflect.ParameterizedType;
import java.util.List;

import org.slf4j.Logger;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;


public abstract class RestBaseService<T> {
    protected static Logger logger = LoggerFactory.getLogger(RestBaseService.class);

    public Class<?> getEntityClass() {
        return (Class<?>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    }

    protected ApplicationEventPublisher applicationEventPublisher;

    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }

    public void publishEvent(ApplicationEvent event) {
        this.applicationEventPublisher.publishEvent(event);
    }

    protected abstract BaseDao<T, String> getRepository();

    public List<T> find(Criteria criteria) {
        return getRepository().find(criteria);
    }

    public T findOne(String id) {
        return (T) getRepository().findById(id);
    }

    public T findOne(Query query) {
        return getRepository().findOne(query);
    }

    public List<T> findAll() {
        return getRepository().findAll();
    }

    public Page<T> findAll(Pageable pageable) {
        return getRepository().findAll(pageable);
    }

    public Page<T> findAll(BaseConditionQuery<T> baseConditionQuery) {
        return getRepository().findAll(baseConditionQuery);
    }

    public Integer findAndModify(Criteria criteria, Update update) {
        return getRepository().findAndModify(criteria, update);
    }

    public T save(T entity) {
        return (T) getRepository().save(entity);
    }

    public List<T> save(Iterable<T> entities) {
        return getRepository().saveAll(entities);
    }

    public void delete(T entity) {
        getRepository().delete(entity);
    }

    public boolean exist(String id) {
        return getRepository().existsById(id);
    }

    public Boolean exists(Query query) {
        return getRepository().exists(query);
    }

    public Long count() {
        return getRepository().count();
    }

}
